import { useSidebar } from "@renderer/components/ui/base/sidebar";
import { useNonPrivateThreadsByUpdated } from "@renderer/queries/hooks/use-threads";
import type { Thread } from "@shared/triplit/types";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";

type SidebarSection =
  | "today"
  | "yesterday"
  | "last7Days"
  | "last30Days"
  | "earlier";

export type GroupedThreads = {
  key: SidebarSection;
  label: string;
  threads: Thread[];
};

export function useSideBar() {
  const { t } = useTranslation("translation", {
    keyPrefix: "sidebar",
  });
  const { state } = useSidebar();
  const { data: threads, isFetching: threadsFetching } =
    useNonPrivateThreadsByUpdated();

  const [searchQuery, setSearchQuery] = useState("");

  const isSidebarCollapsed = state === "collapsed";

  const collectedThreads = useMemo(() => {
    if (!threads) return [];
    return threads.filter((thread) => thread.collected);
  }, [threads]);

  // Cache date boundaries to avoid recalculating on every render
  const dateBoundaries = useMemo(() => {
    const now = new Date();
    now.setHours(0, 0, 0, 0);

    const yesterday = new Date(now);
    yesterday.setDate(now.getDate() - 1);

    const last7Days = new Date(now);
    last7Days.setDate(now.getDate() - 7);

    const last30Days = new Date(now);
    last30Days.setDate(now.getDate() - 30);

    return { now, yesterday, last7Days, last30Days };
  }, []); // No dependencies - recalculate only once per day would be ideal

  /**
   * Creates grouped threads based on time periods
   * @param threadList - Array of threads to group
   * @returns Grouped threads by time periods
   */
  const createGroupedThreads = useMemo(() => {
    const { now, yesterday, last7Days, last30Days } = dateBoundaries;

    const groupConfigs = [
      {
        key: "today" as SidebarSection,
        label: t("section.today"),
        filter: (thread: Thread) => {
          const date = new Date(thread.updatedAt);
          return date >= now;
        },
      },
      {
        key: "yesterday" as SidebarSection,
        label: t("section.yesterday"),
        filter: (thread: Thread) => {
          const date = new Date(thread.updatedAt);
          return date >= yesterday && date < now;
        },
      },
      {
        key: "last7Days" as SidebarSection,
        label: t("section.last7Days"),
        filter: (thread: Thread) => {
          const date = new Date(thread.updatedAt);
          return date >= last7Days && date < yesterday;
        },
      },
      {
        key: "last30Days" as SidebarSection,
        label: t("section.last30Days"),
        filter: (thread: Thread) => {
          const date = new Date(thread.updatedAt);
          return date >= last30Days && date < last7Days;
        },
      },
      {
        key: "earlier" as SidebarSection,
        label: t("section.earlier"),
        filter: (thread: Thread) => {
          const date = new Date(thread.updatedAt);
          return date < last30Days;
        },
      },
    ];

    return (threadList: Thread[]): GroupedThreads[] => {
      if (!threadList.length) return [];

      return groupConfigs.reduce<GroupedThreads[]>((acc, config) => {
        const filteredThreads = threadList.filter(config.filter);

        return filteredThreads.length === 0
          ? acc
          : acc.concat({
              key: config.key,
              label: config.label,
              threads: filteredThreads,
            });
      }, []);
    };
  }, [dateBoundaries, t]);

  /**
   * * All threads grouped by time periods
   */
  const groupedThreads = useMemo<GroupedThreads[]>(() => {
    if (!threads) return [];
    return createGroupedThreads(threads);
  }, [threads, createGroupedThreads]);

  /**
   * * Filtered threads by search query
   */
  const filteredThreads = useMemo(() => {
    if (!threads) return [];

    return threads.filter((thread) => {
      if (!searchQuery.trim()) return true;

      const query = searchQuery.toLowerCase();
      return thread.title.toLowerCase().includes(query);
    });
  }, [threads, searchQuery]);

  /**
   * * Filtered threads grouped by time periods (for search mode)
   */
  const filteredGroupedThreads = useMemo<GroupedThreads[]>(() => {
    if (!searchQuery.trim()) return [];
    return createGroupedThreads(filteredThreads);
  }, [filteredThreads, searchQuery, createGroupedThreads]);

  return {
    isSidebarCollapsed,
    groupedThreads,
    collectedThreads,
    filteredThreads,
    filteredGroupedThreads,
    searchQuery,
    setSearchQuery,
    threadsFetching,
  };
}
